#include "common.h"
QMap  <tcp_socket*,QSharedPointer<M_Socket>>  Common::tcp_server_SocketMap;        //t_socket集合
QReadWriteLock   Common::tcp_server_SocketMapLock;                                 //t_socket读写锁
QMap<local_socket*,QSharedPointer<M_Socket>> Common::localSocket_Map;              //l_socketMAP
QReadWriteLock   Common::localSocket_MapLock;                                      //l_socket读写锁
SQLData Common::mysql_data;                                                        //数据库信息
QReadWriteLock   Common::SQL_Lock;                                                 //数据库信息读写锁
QMap<QString,QSharedPointer<Caculate_Task>>     Common::CaculateTask;                  //计算任务列表
QReadWriteLock   Common::CaculateTask_lock;                                          //计算任务锁
QList<LocalSocket_UnSendData>      Common::Localsocket_unsenddata;                             //本地socket未发送的任务
QReadWriteLock   Common::Localsocket_unsenddataLock;                                 //本地socket未发送任务读写锁
QMap<QString,QString>      Common::Dll_Md5;                                          //本地DLL文件对应MD5值
QReadWriteLock   Common::Dll_Md5lock;                                                //本地DLL文件对应MD5值读写锁
QStringList      Common::SQL_write;                                                  //sql批量写入
QMutex           Common::SQL_writeLock;                                              //sql锁
QStringList      Common::Logdata;                                                    //日志内容
QReadWriteLock   Common::LogdataLock;                                                //日志锁

QReadWriteLock   Common::ConfigureLock;                                              //配置锁
bool             Common::Log_Open=true;                                              //日志是否开启
int              Common::Log_Size;                                                   //日志保存大小
int              Common::TcpPort;                                                    //TCP监听端口
int              Common::TcpHandleThreadNum;                                         //TCP处理线程数量
QString          Common::LocalPort;                                                  //Local监听端口
QString          Common::SQL_IP;                                                     //数据库IP
QString          Common::SQL_DBname;                                                 //数据库名称
QString          Common::SQL_UserName;                                               //数据库账号
QString          Common::SQL_Password;                                               //数据库密码
int              Common::Handle_Count;                                               //处理线程数量
int              Common::distribution_multiple=2;                                    //分配任务倍数
Common::Common()
{

}

QSharedPointer<M_Socket> Common::GetLocal_Socket()
{
    localSocket_MapLock.lockForRead();
    bool isempty=localSocket_Map.isEmpty();
    if (isempty)
    {
        localSocket_MapLock.unlock();
        return NULL;
    }
    QMap<local_socket*,QSharedPointer<M_Socket>>::const_iterator i=localSocket_Map.begin();
    localSocket_MapLock.unlock();
    return i.value();
}

QSharedPointer<M_Socket> Common::GetFree_Caculatenode()
{
    tcp_server_SocketMapLock.lockForRead();
    bool isempty=tcp_server_SocketMap.isEmpty();

    if (isempty)
    {
        tcp_server_SocketMapLock.unlock();
        return NULL;
    }
    QSharedPointer<M_Socket> socket;
    QMap  <tcp_socket*,QSharedPointer<M_Socket>>::const_iterator i;
    for (i = tcp_server_SocketMap.constBegin(); i != tcp_server_SocketMap.constEnd(); ++i) {    //对QMAP进行遍历
        i.value().data()->lock.lockForWrite();                         //对MSOCKET上锁
        // qDebug()<<i.value().data()->Caculate_status<<QThread::currentThreadId();
        //分配方式改为计算线程的倍数

        if(i.value().data()->task_id.size()<(distribution_multiple*i.value().data()->Caculate_status.size()))
        {

            if(i.value().data()->Caculate_status.size()>i.value().data()->task_id.size())
            {
                int num= i.value().data()->Caculate_status.indexOf(Cfree);
                if(num!=-1)
                {
                    i.value().data()->Caculate_status[num]=Caculating;
                }
            }

            socket=i.value();
            i.value().data()->lock.unlock();
            break;
        }

        i.value().data()->lock.unlock();
    }
    tcp_server_SocketMapLock.unlock();
    return socket;
}

QSharedPointer<Decomposition_Task>   Common::GetFree_Decomposition_Task()
{

    CaculateTask_lock.lockForRead();
    // qDebug()<<"查找空闲计算任务"<<QThread::currentThreadId();
    //qDebug()<<CaculateTask.size()<<QThread::currentThreadId();
    if (CaculateTask.isEmpty())
    {
        CaculateTask_lock.unlock();
        return NULL;
    }
    QSharedPointer<Decomposition_Task> Ctask;
    QMap<QString,QSharedPointer<Caculate_Task>>::const_iterator i;

    for (i = CaculateTask.constBegin(); i != CaculateTask.constEnd(); ++i) {    //对QMAP进行遍历
        //防止遍历时计算任务删除导致崩溃
        //         if(i.value().isNull())
        //         {
        //             continue;
        //         }

        if(i.value().data()->Taskisfinish()=="N")
        {
            i.value().data()->unfinish_task_lock.lockForWrite();

            if(!i.value().data()->Decomposition_unfinish_task.isEmpty())
            {
                if(i.value().data()->Decomposition_unfinish_task.size()%50==0)
                    qDebug()<<i.value().data()->Decomposition_unfinish_task.size()<<QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
                Ctask=i.value().data()->Decomposition_unfinish_task.begin().value();
                i.value().data()->Decomposition_unfinish_task.remove(Ctask.data()->getTaskid());
                i.value().data()->unfinish_task_lock.unlock();
                i.value().data()->Caculating_task_lock.lockForWrite();
                i.value().data()->Decomposition_Caculating_task[Ctask.data()->getTaskid()]=Ctask;
                //         qDebug()<<Ctask.data()->getTaskid();
                i.value().data()->Caculating_task_lock.unlock();
                break;
            }
            i.value().data()->unfinish_task_lock.unlock();
        }

    }
    CaculateTask_lock.unlock();
    return Ctask;
}


